﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;

namespace GameNod
{
    class Game
    {
        private List<ConsoleNode> nodes;
        private readonly GameField field;
        private GameNode snake;
        private readonly Painter paint;
        private ConsoleNode target;
        private List<ConsoleNode> nodesInNewRound;
        private readonly Random rnd = new Random();
        private int nodesCount;
        private List<GameNode> usedCoordinates;

        public Game(GameField gameField, Painter painter, int nodeCount)
        {
            field = gameField;
            nodesCount = nodeCount;
            paint = painter;
            nodes = new List<ConsoleNode>();
            nodesInNewRound = new List<ConsoleNode>();
            usedCoordinates = new List<GameNode>();

            snake = new GameNode(rnd.Next(field.StartX + 1, field.Width + field.StartX),
                rnd.Next(field.StartY + 1, field.Height + field.StartY));
        }
        
        private void CreateNodeList(int nodesCount)
        {
            for (int i = 0; i < nodesCount;)
            {
              int startX = rnd.Next(field.StartX+1, field.Width + field.StartX);
              int startY = rnd.Next(field.StartY+1, field.Height + field.StartY);
              if (CrossNodes(startX, startY))
                 {
                   nodes.Add(new ConsoleNode(startX, startY, (ConsoleColor)rnd.Next(1, 15), (char)(i + 41)));
                   i++;
                 }
            }
        }


        public void CreateTarget()
        {
            bool check = false;
            while (!check)
            {
                int X = rnd.Next(field.StartX + 1, field.Width + field.StartX);
                int Y = rnd.Next(field.StartY + 1, field.Height + field.StartY);
                if (CrossNodes(X, Y))
                {
                    target = new ConsoleNode(X, Y, ConsoleColor.White, 'X');
                    check = true;
                }
            }
        }
        public void StartGame()
        {
            CreateNodeList(nodesCount);
            SpiralNode difNode = new SpiralNode(rnd.Next(field.StartX + 1, field.Width + field.StartX), 
                rnd.Next(field.StartY + 1, field.Height + field.StartY), ConsoleColor.Red, 'K');
            nodes.Add(difNode);
            
            bool gameOver = false;
            do
            {
                Console.Clear();
                CreateTarget();
                GeneraterandomCoordinates(difNode);
                while (nodes.Count != 1)
                {
                    paint.DraweGameFieldFrame(field);
                    paint.DrawNodes(target);
                    for (int i = 0; i < nodes.Count; i++)
                    {
                        paint.ClearGameNode(nodes[i]);
                        nodes[i].Move(CheckPosition);
                        paint.DrawNodes(nodes[i]);

                    }
                    for (int i = 0; i < nodes.Count; i++)
                    {
                        if (IsOnTarget(nodes[i]))
                        {
                            paint.DrawNodes(target);
                            nodesInNewRound.Add(nodes[i]);
                            nodes.RemoveAt(i);
                            if (nodes.Count == 1)
                            {
                                paint.DrawListAndMessage(nodesInNewRound, field, 5, "Winners");
                                paint.DrawListAndMessage(nodes, field, 15, "Loosers");
                            }
                        }
                    }
                }
                Console.ReadKey();

                if (nodesInNewRound.Count == 1)
                {
                    gameOver = true;
                }
                else
                {
                    nodes = nodesInNewRound;
                    //NewPositionNodeNewRoundGame(nodesInNewRound.Count);
                    foreach (var node in nodesInNewRound)
                    {
                        GeneraterandomCoordinates(node);
                    }
                    nodesInNewRound = new List<ConsoleNode>();
                }
            }
            while (!gameOver);



            
            //ConsoleKeyInfo turn = Console.ReadKey();
            //snakeNode.ClearGameNode(snake);
            //MovePlayerNode(turn.Key, snake);
            //snakeNode.DrawGameNode(snake, ConsoleColor.Green);

        }

        //public bool IsNodeMove()
        //{

        //}


        public bool CrossNodes(int x, int y)
        {
            foreach (var node in nodes)
            {
                if (node.X == x && node.Y == y)
                    return false;
            }
            return true;
        }

        public bool IsOnField(int x, int y)
        {
            if ((x >= field.StartX) && (x < field.Width + field.StartX)
                && (y >= field.StartY) && (y < field.Height + field.StartY))
                return true;
            return false;
        }

        private bool IsOnTarget(ConsoleNode node)
        {
            if (node.X == target.X && node.Y == target.Y)
                return true;
            return false;
        }

        public Position CheckPosition(int x, int y)
        {
            if (!CrossNodes(x, y))
                return Position.Node;
            if (!IsOnField(x, y))
                return Position.Border;
            return Position.Free;
        }

        private void NewPositionNodeNewRoundGame(int nodesCount)
        {
            for (int i = 0; i < nodes.Count; i++)
            {
                for (int j = 0; j <= 10; j++)
                {
                    nodes[i].Move(CheckPosition);
                }
            }
        }

        private ConsoleNode GeneraterandomCoordinates(ConsoleNode node)
        {
                int newX = rnd.Next(field.StartX + 1, field.Width + field.StartX);
                int newY = rnd.Next(field.StartY + 1, field.Height + field.StartY);
                if (CrossNodes(newX, newY))
                {
                    node.X = newX;
                    node.Y = newY;
                }
            return node;
        }

        public void MovePlayerNode(ConsoleKey turn, GameNode snake)
        {
            if (turn != ConsoleKey.UpArrow && turn != ConsoleKey.DownArrow && 
                turn != ConsoleKey.LeftArrow && turn != ConsoleKey.RightArrow)
                throw new ArgumentException();
            else if (turn == ConsoleKey.UpArrow && snake.Y > field.StartY)
                snake.MoveUp();
            else if (turn == ConsoleKey.DownArrow && snake.Y < field.StartY + field.Height - 1)
                snake.MoveDown();
            else if (turn == ConsoleKey.LeftArrow && snake.X > field.StartX)
                snake.MoveLeft();
            else if (snake.X < field.StartX + field.Width - 1)
                snake.MoveRight();
        }
        
    }

    enum Position
    {
        Node,
        Border,
        Free
    }
}
